package com.vhly.ddxdecompiler.dexreader.file.mixeditem;

import com.vhly.ddxdecompiler.dexreader.file.DexFile;
import com.vhly.ddxdecompiler.dexreader.file.dalv.code.*;
import com.vhly.ddxdecompiler.dexreader.io.DexInputStream;

import java.io.DataOutputStream;
import java.io.IOException;

/**
 * Created by IntelliJ IDEA.
 * User: vhly
 * Date: 2009-10-15
 * Time: 12:44:06
 *
 * @author vhly[FR]
 */
public final class CodeItem extends OffsettedItem {

    private DexFile dex;

    short regSz;
    short insSz;
    short outsSz;
    short triesSz;
    int debugOff;
    int insnsSz;

    DalvInsnList insns;
    CatchStructs tries;

    public CodeItem(DexFile dexFile) {
        super(4, 0);
        dex = dexFile;
    }

    /**
     * 读取数据
     *
     * @param din 输入流
     * @throws java.io.IOException 异常
     */
    public void read(DexInputStream din) throws IOException {
        regSz = din.readShort();
        insSz = din.readShort();
        outsSz = din.readShort();
        triesSz = din.readShort();
        debugOff = din.readInt();
        insnsSz = din.readInt(); // 真实指令数量
        readCodes(din);
//        System.out.println("[Debug] CodeItem readCode");
        int catchSize = triesSz;
        boolean needPadding = (insnsSz & 0x0f) == 1;
        if (catchSize > 0) {
            if (needPadding) {
                din.readShort();
            }
            tries = new CatchStructs(dex);
            tries.triesCount = catchSize;
            tries.read(din);
        }
    }

    private void readCodes(DexInputStream din) throws IOException {
        // TODO 获取指令
        int size = insnsSz;
        if (size > 0) {
            insns = new DalvInsnList();
            int first;
            DalvInsn insn;
            for (int i = 0; i < size; i++) {
                // TODO 读取指令标记，并且添加到 DalvInsnList中
                first = din.readShort();
                if (first == DalvInsn.INSN_ARRAYDATA) {
                    insn = new ArrayData();
                } else if (first == DalvInsn.INSN_SWITCHDATA_PACK) {
                    insn = new SwitchData(true);
                } else if (first == DalvInsn.INSN_SWITCHDATA) {
                    insn = new SwitchData(false);
                } else {
                    insn = new FixedSizeInsn(first);
                }
                i += insn.read(din);
                insns.addInsn(insn);
            }
        }

    }

    /**
     * 输出数据
     *
     * @param dout 输出流
     * @throws java.io.IOException 异常
     */
    public void write(DataOutputStream dout) throws IOException {
    }
}
